using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using UpdaterManagement.Data;
using UpdaterManagement.Models;
using Microsoft.AspNetCore.Authorization;

namespace UpdaterManagement.Controllers
{
    [Authorize]
    public class VersionController : Controller
    {
        private readonly ApplicationDbContext _context;
        private readonly IWebHostEnvironment _environment;

        public VersionController(ApplicationDbContext context, IWebHostEnvironment environment)
        {
            _context = context;
            _environment = environment;
        }

        public async Task<IActionResult> Index(int? productId, int? enterpriseId, int page = 1, int pageSize = 5)
        {
            var query = _context.VersionReleases.Include(v => v.Enterprise).AsQueryable();
            
            if (productId.HasValue)
            {
                var product = await _context.Products.FindAsync(productId.Value);
                if (product != null)
                {
                    query = query.Where(v => v.ProductName == product.Name);
                }
            }
            
            if (enterpriseId.HasValue)
            {
                query = query.Where(v => v.EnterpriseId == enterpriseId.Value);
            }
            
            var totalCount = await query.CountAsync();
            var versions = await query
                .OrderByDescending(v => v.CreatedTime)
                .Skip((page - 1) * pageSize)
                .Take(pageSize)
                .ToListAsync();
            
            ViewBag.ProductId = productId;
            ViewBag.EnterpriseId = enterpriseId;
            ViewBag.Products = await _context.Products.ToListAsync();
            ViewBag.Enterprises = await _context.Enterprises.ToListAsync();
            ViewBag.CurrentPage = page;
            ViewBag.PageSize = pageSize;
            ViewBag.TotalCount = totalCount;
            ViewBag.TotalPages = (int)Math.Ceiling((double)totalCount / pageSize);
            
            return View(versions);
        }

        public async Task<IActionResult> Create()
        {
            ViewBag.Enterprises = await _context.Enterprises.Where(e => e.IsActive).ToListAsync();
            ViewBag.Products = await _context.Products.ToListAsync();
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Create(VersionRelease model, IFormFile? versionFile, IFormFile? manualFile)
        {
            try
            {
                if (versionFile != null)
                {
                    var s3Url = await UploadToS3(versionFile, model.ProductName, model.Version);
                    Console.WriteLine(s3Url);
                    model.VersionUrl = s3Url;
                    model.FilePath = await SaveFile(versionFile, "versions");
                }
                
                if (manualFile != null)
                    model.ManualPath = await SaveFile(manualFile, "manuals");

                model.CreatedTime = DateTime.Now;
                model.IsActive = true;
                
                _context.VersionReleases.Add(model);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", $"保存失败: {ex.Message}");
            }
            
            ViewBag.Enterprises = await _context.Enterprises.Where(e => e.IsActive).ToListAsync();
            ViewBag.Products = await _context.Products.ToListAsync();
            return View(model);
        }

        [AllowAnonymous]
        public async Task<IActionResult> GetProductList()
        {
            var products = await _context.Products
                .Select(p => new { ProductId = p.Id.ToString(), p.Name, Type = p.Type })
                .ToListAsync();
            return Json(products);
        }

        public async Task<IActionResult> Details(int id)
        {
            var version = await _context.VersionReleases.Include(v => v.Enterprise).FirstOrDefaultAsync(v => v.Id == id);
            if (version == null) return NotFound();
            return View(version);
        }

        public async Task<IActionResult> Edit(int id)
        {
            var version = await _context.VersionReleases.FindAsync(id);
            if (version == null) return NotFound();
            
            ViewBag.Enterprises = await _context.Enterprises.Where(e => e.IsActive).ToListAsync();
            ViewBag.Products = await _context.Products.ToListAsync();
            return View(version);
        }

        [HttpPost]
        public async Task<IActionResult> Edit(int id, VersionRelease model, IFormFile? versionFile, IFormFile? manualFile)
        {
            if (id != model.Id) return NotFound();
            
            try
            {
                var existingVersion = await _context.VersionReleases.FindAsync(id);
                if (existingVersion == null) return NotFound();
                
                // 更新基本信息
                existingVersion.ProductId = model.ProductId;
                existingVersion.ProductName = model.ProductName;
                existingVersion.EnterpriseId = model.EnterpriseId;
                existingVersion.Description = model.Description;
                existingVersion.VersionUrl = model.VersionUrl;
                existingVersion.DeployType = model.DeployType;
                existingVersion.IsActive = model.IsActive;
                
                // 处理版本文件上传
                if (versionFile != null)
                {
                    var s3Url = await UploadToS3(versionFile, model.ProductName, model.Version);
                    existingVersion.VersionUrl = s3Url;
                    existingVersion.FilePath = await SaveFile(versionFile, "versions");
                }
                
                // 处理手册文件上传
                if (manualFile != null)
                {
                    existingVersion.ManualPath = await SaveFile(manualFile, "manuals");
                }
                
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", $"更新失败: {ex.Message}");
            }
            
            ViewBag.Enterprises = await _context.Enterprises.Where(e => e.IsActive).ToListAsync();
            ViewBag.Products = await _context.Products.ToListAsync();
            return View(model);
        }

        [HttpPost]
        public async Task<IActionResult> Delete(int id)
        {
            var version = await _context.VersionReleases.FindAsync(id);
            if (version != null)
            {
                _context.VersionReleases.Remove(version);
                await _context.SaveChangesAsync();
            }
            return RedirectToAction(nameof(Index));
        }

        [HttpGet]
        [AllowAnonymous]
        public async Task<IActionResult> GetVersions(string productName)
        {
            var versions = await _context.VersionReleases
                .Where(v => v.ProductName == productName && v.IsActive)
                .OrderByDescending(v => v.CreatedTime)
                .Select(v => v.Version)
                .ToListAsync();
            return Json(versions);
        }

        [HttpGet]
        [AllowAnonymous]
        public async Task<IActionResult> GetProductNames()
        {
            var productNames = await _context.VersionReleases
                .Where(v => v.IsActive)
                .Select(v => v.ProductName)
                .Distinct()
                .ToListAsync();
            return Json(productNames);
        }

        private async Task<string> SaveFile(IFormFile file, string folder)
        {
            var uploadsFolder = Path.Combine(_environment.WebRootPath, "uploads", folder);
            Directory.CreateDirectory(uploadsFolder);
            
            var fileName = $"{Guid.NewGuid()}_{file.FileName}";
            var filePath = Path.Combine(uploadsFolder, fileName);
            
            using var stream = new FileStream(filePath, FileMode.Create);
            await file.CopyToAsync(stream);
            
            return $"/uploads/{folder}/{fileName}";
        }
        
        private async Task<string> UploadToS3(IFormFile file, string productName, string version)
        {
            var s3Client = new Amazon.S3.AmazonS3Client("AKIARNK3H2LQS4MYN673", "HhSadU4OTc/z2tSNzD0fwP+VgDpnnkuXCywApe7C", Amazon.RegionEndpoint.CNNorthWest1);
            
            var fileName = $"{productName}_{version}_{Path.GetFileName(file.FileName)}";
            var bucketName = "wpaydp";
            var key = $"WUPAY-PRD/{fileName}";
            
            using var stream = file.OpenReadStream();
            var request = new Amazon.S3.Model.PutObjectRequest
            {
                BucketName = bucketName,
                Key = key,
                InputStream = stream,
                ContentType = file.ContentType,
                CannedACL = Amazon.S3.S3CannedACL.PublicRead
            };
            
            await s3Client.PutObjectAsync(request);
            
            return $"https://{bucketName}.s3.cn-northwest-1.amazonaws.com.cn/{key}";
        }
    }
}